﻿using Iot.Device.Pn532;
using Iot.Device.Sht3x;
using IotDeviceToolHepler;

using IotDeviceToolHepler.Model.Device;
using IotDeviceToolHepler.Utils;
using Models.Common;
using Models.Device;
using Models.TaskPlain;
using Newtonsoft.Json;

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Device.I2c;
using System.Drawing.Drawing2D;
using System.IO.Ports;
using System.Text;
using System.Threading;
using UnitsNet;
using static Models.Common.EnumDeviceState;
using System.Threading.Tasks;
using GatewayClient.MQ;
using Microsoft.Extensions.Logging;
using UtilsCache;
using static Iot.Device.HardwareMonitor.OpenHardwareMonitor;
using UtilsBase;
using UtilsMQ;
using GatewayClient.Models;


namespace GatewayClient.Service
{
    public class ServiceHandleRS485
    {
        //static List<ModelRS485List> ModelRS485Lists = new List<ModelRS485List>();
        /// <summary>
        /// 执行485指令
        /// </summary>
        /// <param name="obj"></param>
        public void gateWayExecuteRS485(MQReqModel<object> mQReqModel)
        {
            CommandLogModel commandLogModel = mQReqModel.toGatewayData;
            try
            {
               // mQReqModel.respMsg = DateTime.Now.ToString("HH:mm:ss.fff");
                ModelCommandAgreement modelCommandAgreement = JsonConvert.DeserializeObject<ModelCommandAgreement>(commandLogModel.parameter);
                ModelCommandAgreementParameter modelCommandAgreementParameter = modelCommandAgreement.agreementParameter;// UtilsObject.DynamicToEntity<ModelCommandAgreementParameter>(modelCommandAgreement.agreementParameter);

                if (modelCommandAgreement.agreementParameter.command != null)
                {
                    List<ModelCommandAgreementParameterCommand> commandList = modelCommandAgreement.agreementParameter.command;// UtilsObject.DynamicToEntity<List<ModelCommandAgreementParameterCommand>>(modelCommandAgreement.agreementParameter.command);
                    if (commandList.Count > 0)
                    {
                        ModelCommandAgreementParameterCommand command = commandList.Where(c => c.key == commandLogModel.key).FirstOrDefault();

                        if (command != null)
                        {
                            if (command.callBackStart == "true")
                            {
                                Task.Run(() =>
                                {
                                    //执行回调操作
                                    new ServiceHandleRS485CallBack().eventListen(mQReqModel);
                                });

                                return;
                            }
                            else if (command.callBackStop == "true")
                            {
                                Task.Run(() =>
                                {
                                    //停止执行回调操作
                                    new ServiceHandleRS485CallBack().stopEventListen(mQReqModel);
                                });

                                return;
                            }
                            commandLogModel.content = command.value;//自定指令   否则使用默认commandLogModel.content指令

                        }
                    }
                }
                //mQReqModel.respMsg = mQReqModel.respMsg + "," + DateTime.Now.ToString("HH:mm:ss.fff");
                ModelRS485Queue parameter = new ModelRS485Queue();
                parameter.portName = modelCommandAgreementParameter.portName;
                parameter.baudRate = modelCommandAgreementParameter.baudRate;
                parameter.sendData = commandLogModel.content;
                parameter.content = mQReqModel;
                ServiceThreadChannelForSerial.writeChannel(JsonConvert.SerializeObject(parameter));
                //这里的主方法是异步操作，可能多个异步，同时写入队列
            }
            catch (Exception ex)
            {
                new ServiceMQPayEvent().handleError(mQReqModel, ex.Message.ToString());
                Console.WriteLine(ex.ToString());
            }
        }


        public async Task runSerialTaskAsync()
        {
          
            string result = "";
            ModelRS485Queue modelCommandAgreementParameter = new ModelRS485Queue();
            //async stream,在没有被生产者明确Complete的情况下，这里会一致阻塞下去
            // channel.Writer.Complete(); //生产者也可以明确告知消费者不会发送任何消息,这里就不再阻塞
            await foreach (var item in ServiceThreadChannelForSerial.channels.Reader.ReadAllAsync())
            {
                try
                {
                    modelCommandAgreementParameter = JsonConvert.DeserializeObject<ModelRS485Queue>(item);
                    result = UtilsSerial.getPortData(modelCommandAgreementParameter.portName, modelCommandAgreementParameter.baudRate, modelCommandAgreementParameter.sendData);        
                    runSerialTaskAsyncHandle(modelCommandAgreementParameter, result);//这里不能使用异步，会数据错乱
                }
                catch (Exception ex)
                {
                    // new UtilsFileHelper().log_WriteMessageAppend("runSerialTask", "指-" + ex.ToString());
                    Console.WriteLine(ex.ToString());
                }

            }
        }

        public void runSerialTaskAsyncHandle(ModelRS485Queue modelCommandAgreementParameter, string result)
        {
            try
            {
                MQReqModel<object> mQReqModel = modelCommandAgreementParameter.content;
                mQReqModel.respMsg = mQReqModel.respMsg + "," + DateTime.Now.ToString("HH:mm:ss.fff");

                CommandLogModel commandLogModel = mQReqModel.toGatewayData;
                ModelReceverData modelDeviceData = new ModelReceverData();

                List<ModelCommandResult> commandResults = new List<ModelCommandResult>();
                ModelCommandResult commandResult = new ModelCommandResult();
                commandResult.name = commandLogModel.name;
                commandResult.key = commandLogModel.key;
                commandResult.value = result;
                commandResults.Add(commandResult);
                modelDeviceData.commandResults = commandResults;

                if (string.IsNullOrEmpty(result))
                {//返回空即为异常
                    new ServiceMQPayEvent().handleError(mQReqModel, "设备无响应");
                    return;
                }

                //推送结果
                mQReqModel.respCode = ResponseCode.SUCCESS;
                // mQReqModel.respMsg = MQEventEnum.Event_State_OK;
                mQReqModel.toServerData = modelDeviceData;
                mQReqModel.respMsg = mQReqModel.respMsg + "," + DateTime.Now.ToString("HH:mm:ss.fff");
                new ServiceMQ_Helper().sendMsg(mQReqModel);
            }
            catch (Exception ex)
            {
                // new UtilsFileHelper().log_WriteMessageAppend("runSerialTask", "指-" + ex.ToString());
                Console.WriteLine(ex.ToString());
            }
        }
    }
}
